/*
 * Created by JFormDesigner on Wed Jun 16 18:29:49 CST 2021
 */

package com.huidian.gitbatchprocessing.ui;

import com.google.common.collect.Lists;
import com.huidian.gitbatchprocessing.git.util.ApplicationUtil;
import com.huidian.gitbatchprocessing.git.util.CredentialsUtil;
import com.huidian.gitbatchprocessing.git.util.GitUtil;
import com.huidian.gitbatchprocessing.git.util.ProjectUtil;
import com.huidian.gitbatchprocessing.ui.constant.DialogConstant;
import com.huidian.gitbatchprocessing.ui.enums.BranchOperateEnum;
import com.huidian.gitbatchprocessing.ui.mycomponent.CheckBoxTableModel;
import com.huidian.gitbatchprocessing.ui.mycomponent.CheckHeaderCellRenderer;
import com.huidian.gitbatchprocessing.ui.mycomponent.ComboBoxItem;
import com.huidian.gitbatchprocessing.ui.service.AbstractBranchOperate;
import com.huidian.gitbatchprocessing.ui.service.BranchOperateFactory;
import com.huidian.gitbatchprocessing.ui.service.dto.*;
import com.intellij.notification.*;
import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import org.eclipse.jgit.lib.Repository;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * 插件的主界面
 * 新增的分支操作，请将其放到 panelBranchOptContainer 这个 JPanel 下，因为点击操作菜单时，会将该 JPanel 下的所有 JPanel隐藏。
 * 新扩展的操作，请实现该接口 {@link AbstractBranchOperate}
 *
 * @author zxb
 * @date 2021/6/16
 */
public class GitBatchProcessingDialog extends JFrame {

    private final Project project;

    /**
     * 组通知
     */
    public static final NotificationGroup GROUP_DISPLAY_ID_INFO =
            new NotificationGroup("GIT BATCH PROCESSING GROUP",
                    NotificationDisplayType.STICKY_BALLOON, true);

    /**
     * cpu 核心数
     */
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();

    private static final String COLUMN_NAME_FIRST = "";
    private static final String COLUMN_NAME_SECOND = "项目名";

    /**
     * IO 密集型线程池
     */
    private static final ExecutorService THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CPU_COUNT, CPU_COUNT * 2,
            0, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(CPU_COUNT), new ThreadPoolExecutor.CallerRunsPolicy());

    public GitBatchProcessingDialog(Project project) {
        ProjectUtil.set(project);
        this.project = project;
        initComponents();
        customInit();
    }

    // ======================== 业务代码 ======================= //

    private List<Repository> getSelectedRepositories() {
        CheckBoxTableModel checkBoxTableModel = (CheckBoxTableModel) table1.getModel();
        List<List<Object>> rowDataList = checkBoxTableModel.getRowDataList();
        return rowDataList.stream()
                .filter(e -> (Boolean) e.get(DialogConstant.COLUMN_INDEX_0))
                .map(e -> (Repository) e.get(DialogConstant.COLUMN_INDEX_1))
                .collect(Collectors.toList());
    }

    /**
     * 异步执行；todo 由于异步执行，调用消息框会出错，因此暂时采用单线程执行
     *
     * @param selectedRepositories
     * @param instance
     * @return
     */
    private List<String> executeMultiThread(BaseBranchDto baseBranchDto, List<Repository> selectedRepositories, AbstractBranchOperate instance) {
        List<Future<String>> executeFutureList = new ArrayList<>();
        for (Repository repository : selectedRepositories) {
            // 异步操作仓库
            Future<String> executeFuture = THREAD_POOL_EXECUTOR.submit(() -> StringUtil.join("执行项目【",
                    repository.getWorkTree().getName(), "】：", instance.executeWithNoException(baseBranchDto, repository)));
            executeFutureList.add(executeFuture);
        }
        return executeFutureList.stream().map(executeFuture -> {
            try {
                return executeFuture.get();
            } catch (InterruptedException | ExecutionException interruptedException) {
                return interruptedException.getMessage();
            }
        }).collect(Collectors.toList());
    }

    /**
     * 单线程执行
     *
     * @param selectedRepositories
     * @param instance
     * @return
     */
    private List<String> executeSingleThread(BaseBranchDto baseBranchDto, List<Repository> selectedRepositories, AbstractBranchOperate instance) {
        this.setVisible(Boolean.FALSE);
        List<String> executeMsgList = new ArrayList<>();
        ProgressManager.getInstance().run(new Task.ConditionalModal(project, "分支操作", false, PerformInBackgroundOption.DEAF) {
            @Override
            public void run(@NotNull ProgressIndicator progressIndicator) {
                progressIndicator.setIndeterminate(Boolean.FALSE);
                // 进度
                double progressRate = 0.1D;
                // 步长
                double step = 1.0D / selectedRepositories.size();
                for (Repository repository : selectedRepositories) {
                    String executeResult = instance.executeWithNoException(baseBranchDto, repository);
                    String msg = StringUtil.join("执行项目【", repository.getWorkTree().getName(), "】：", executeResult);
                    progressIndicator.setFraction(progressRate);
                    progressIndicator.setText(msg);
                    executeMsgList.add(msg);
                    progressRate += step;
                }
                // 完成
                progressIndicator.setFraction(1.0);
                progressIndicator.setText("finished!");
            }
        });
        this.setVisible(Boolean.TRUE);
        return executeMsgList;
    }

    private void execute(BaseBranchDto baseBranchDto) {
        JComboBox<String> comboBox = comboBoxOpt;
        ComboBoxItem comboBoxItem = (ComboBoxItem) comboBox.getSelectedItem();
        AbstractBranchOperate instance = BranchOperateFactory.getInstance(comboBoxItem.getKey());
        List<Repository> selectedRepositories = getSelectedRepositories();
        if (selectedRepositories.size() == 0) {
            Messages.showWarningDialog("请选择需要操作的项目！", "警告");
            return;
        }
        if (!tryGetCredentialsConfig()) {
            return;
        }
        List<String> resultList = executeSingleThread(baseBranchDto, selectedRepositories, instance);
        Notification notification = GROUP_DISPLAY_ID_INFO.createNotification(beautifulExecuteMsg(resultList), NotificationType.INFORMATION);
        Notifications.Bus.notify(notification);
    }

    /**
     * 尝试获取本项目的认证信息
     */
    private boolean tryGetCredentialsConfig() {
        try {
            CredentialsUtil.getCredentialsConfigFromLocal(project);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private String beautifulExecuteMsg(List<String> executeMsgList) {
        StringBuilder stringBuilder = new StringBuilder();
        for (String msg : executeMsgList) {
            stringBuilder.append(msg).append("\n");
        }
        return stringBuilder.toString();
    }

    // ======================== 组件事件 ======================= //


    private void btnConfirmCreateActionPerformed(ActionEvent e) {
        BaseBranchDto baseBranchDto = new CreateBranchDto()
                .setSourceBranchName(textFieldCreateSource.getText())
                .setTargetBranchName(textFieldCreateTarget.getText());
        this.execute(baseBranchDto);
    }

    private void btnConfirmMergeActionPerformed(ActionEvent e) {
        BaseBranchDto baseBranchDto = new MergeBranchDto()
                .setSourceBranchName(textFieldMergeSource.getText())
                .setTargetBranchName(textFieldMergeTarget.getText());
        this.execute(baseBranchDto);
    }

    private void btnConfirmDeleteActionPerformed(ActionEvent e) {
        BaseBranchDto baseBranchDto = new DeleteBranchDto()
                .setSourceBranchName(textFieldDeleteSource.getText());
        this.execute(baseBranchDto);
    }

    private void btnConfirmCheckoutActionPerformed(ActionEvent e) {
        BaseBranchDto baseBranchDto = new CheckoutBranchDto()
                .setSourceBranchName(textFieldCheckoutSource.getText());
        this.execute(baseBranchDto);
    }

    private void comboBoxOptActionPerformed(ActionEvent e) {
        ComboBoxItem boxItem = (ComboBoxItem) comboBoxOpt.getSelectedItem();
        if (boxItem == null) {
            return;
        }
        setAllBranchOptPanelVisible(Boolean.FALSE);
        BranchOperateEnum branchOperateEnum = BranchOperateEnum.getByKey(boxItem.getKey());
        // fixme 新增了操作需要在此处扩展；让下拉框与 panel 关联起来
        switch (branchOperateEnum) {
            case CREATE_BRANCH:
                panelCreateBranch.setVisible(Boolean.TRUE);
                break;
            case DELETE_BRANCH:
                panelDeleteBranch.setVisible(Boolean.TRUE);
                break;
            case CHECKOUT_BRANCH:
                panelCheckputBranch.setVisible(Boolean.TRUE);
                break;
            case MERGE_BRANCH:
                panelMergeBranch.setVisible(Boolean.TRUE);
                break;
            default:
                break;
        }
    }

    private void menuItemUserInfoActionPerformed(ActionEvent e) {
        try {
            CredentialsUtil.showUserPasswordInputDialog(project);
        } catch (Exception exception) {
            // pass
        }
    }

    // ======================== 组件初始化 ======================= //

    private void customInit() {
        // 自定义初始化
        Dimension dimension = new Dimension(725, 470);
        this.setMaximumSize(dimension);
        this.setSize(dimension);
        this.setAllBranchOptPanelVisible(Boolean.FALSE);
        this.setAlwaysOnTop(false);
        this.setResizable(false);
        this.panelCreateBranch.setVisible(Boolean.TRUE);


        comboBoxOpt.setModel(new DefaultComboBoxModel(getComboBoxItems()));
        table1.setModel(getTableModel());
        renderTableWidth();
        table1.getTableHeader().setDefaultRenderer(new CheckHeaderCellRenderer(table1));
        scrollPane1.updateUI();

        ApplicationUtil.getFrameInstance().setFrame(this);
    }

    private void initComponents() {
        // JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
        menuBar1 = new JMenuBar();
        menuUserInfo = new JMenu();
        menuItemUserInfo = new JMenuItem();
        scrollPane1 = new JScrollPane();
        table1 = new JTable();
        labelTableTitle = new JLabel();
        panelBranchOptContainer = new JPanel();
        label1 = new JLabel();
        comboBoxOpt = new JComboBox<>();
        panelCreateBranch = new JPanel();
        labelCreateSource = new JLabel();
        labelCreateTarget = new JLabel();
        textFieldCreateSource = new JTextField();
        textFieldCreateTarget = new JTextField();
        btnConfirmCreate = new JButton();
        panelMergeBranch = new JPanel();
        labelaMergeSource = new JLabel();
        labelMergeTarget = new JLabel();
        textFieldMergeSource = new JTextField();
        textFieldMergeTarget = new JTextField();
        btnConfirmMerge = new JButton();
        panelDeleteBranch = new JPanel();
        labelaDeleteSource = new JLabel();
        textFieldDeleteSource = new JTextField();
        btnConfirmDelete = new JButton();
        panelCheckputBranch = new JPanel();
        labelaCheckoutSource = new JLabel();
        textFieldCheckoutSource = new JTextField();
        btnConfirmCheckout = new JButton();

        //======== this ========
        setTitle("Git Tool");
        var contentPane = getContentPane();
        contentPane.setLayout(null);

        //======== menuBar1 ========
        {

            //======== menuUserInfo ========
            {
                menuUserInfo.setText("\u8bbe\u7f6e");

                //---- menuItemUserInfo ----
                menuItemUserInfo.setText("git \u7528\u6237\u4fe1\u606f");
                menuItemUserInfo.addActionListener(e -> menuItemUserInfoActionPerformed(e));
                menuUserInfo.add(menuItemUserInfo);
            }
            menuBar1.add(menuUserInfo);
        }
        setJMenuBar(menuBar1);

        //======== scrollPane1 ========
        {

            //---- table1 ----
            table1.setModel(new DefaultTableModel());
            table1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
            scrollPane1.setViewportView(table1);
        }
        contentPane.add(scrollPane1);
        scrollPane1.setBounds(5, 30, 700, 215);

        //---- labelTableTitle ----
        labelTableTitle.setText("\u8bf7\u9009\u62e9\u9879\u76ee\uff1a");
        contentPane.add(labelTableTitle);
        labelTableTitle.setBounds(10, 5, 90, 20);

        //======== panelBranchOptContainer ========
        {
            panelBranchOptContainer.setLayout(null);

            //---- label1 ----
            label1.setText("\u8bf7\u9009\u62e9\u64cd\u4f5c\uff1a");
            panelBranchOptContainer.add(label1);
            label1.setBounds(5, 5, 95, 30);

            //---- comboBoxOpt ----
            comboBoxOpt.setModel(new DefaultComboBoxModel<>(new String[] {
                "\u521b\u5efa\u5206\u652f",
                "\u5408\u5e76\u5206\u652f",
                "\u5207\u6362\u5206\u652f",
                "\u5220\u9664\u5206\u652f"
            }));
            comboBoxOpt.addActionListener(e -> comboBoxOptActionPerformed(e));
            panelBranchOptContainer.add(comboBoxOpt);
            comboBoxOpt.setBounds(80, 5, 110, comboBoxOpt.getPreferredSize().height);

            //======== panelCreateBranch ========
            {
                panelCreateBranch.setLayout(null);

                //---- labelCreateSource ----
                labelCreateSource.setText("\u6e90\u5206\u652f\uff1a");
                panelCreateBranch.add(labelCreateSource);
                labelCreateSource.setBounds(0, 17, 50, 17);

                //---- labelCreateTarget ----
                labelCreateTarget.setText("\u65b0\u5efa\u5206\u652f\uff1a");
                panelCreateBranch.add(labelCreateTarget);
                labelCreateTarget.setBounds(0, 55, 75, 17);
                panelCreateBranch.add(textFieldCreateSource);
                textFieldCreateSource.setBounds(65, 10, 415, 30);
                panelCreateBranch.add(textFieldCreateTarget);
                textFieldCreateTarget.setBounds(65, 50, 415, 30);

                //---- btnConfirmCreate ----
                btnConfirmCreate.setText("\u521b\u5efa");
                btnConfirmCreate.addActionListener(e -> btnConfirmCreateActionPerformed(e));
                panelCreateBranch.add(btnConfirmCreate);
                btnConfirmCreate.setBounds(500, 20, 100, 50);

                {
                    // compute preferred size
                    Dimension preferredSize = new Dimension();
                    for(int i = 0; i < panelCreateBranch.getComponentCount(); i++) {
                        Rectangle bounds = panelCreateBranch.getComponent(i).getBounds();
                        preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
                        preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
                    }
                    Insets insets = panelCreateBranch.getInsets();
                    preferredSize.width += insets.right;
                    preferredSize.height += insets.bottom;
                    panelCreateBranch.setMinimumSize(preferredSize);
                    panelCreateBranch.setPreferredSize(preferredSize);
                }
            }
            panelBranchOptContainer.add(panelCreateBranch);
            panelCreateBranch.setBounds(80, 40, 620, 85);

            //======== panelMergeBranch ========
            {
                panelMergeBranch.setVisible(false);
                panelMergeBranch.setLayout(null);

                //---- labelaMergeSource ----
                labelaMergeSource.setText("\u6e90\u5206\u652f\uff1a");
                panelMergeBranch.add(labelaMergeSource);
                labelaMergeSource.setBounds(0, 17, 50, 17);

                //---- labelMergeTarget ----
                labelMergeTarget.setText("\u76ee\u6807\u5206\u652f\uff1a");
                panelMergeBranch.add(labelMergeTarget);
                labelMergeTarget.setBounds(0, 55, 75, 17);
                panelMergeBranch.add(textFieldMergeSource);
                textFieldMergeSource.setBounds(65, 10, 415, 30);
                panelMergeBranch.add(textFieldMergeTarget);
                textFieldMergeTarget.setBounds(65, 50, 415, 30);

                //---- btnConfirmMerge ----
                btnConfirmMerge.setText("\u5408\u5e76");
                btnConfirmMerge.addActionListener(e -> btnConfirmMergeActionPerformed(e));
                panelMergeBranch.add(btnConfirmMerge);
                btnConfirmMerge.setBounds(500, 20, 100, 50);

                {
                    // compute preferred size
                    Dimension preferredSize = new Dimension();
                    for(int i = 0; i < panelMergeBranch.getComponentCount(); i++) {
                        Rectangle bounds = panelMergeBranch.getComponent(i).getBounds();
                        preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
                        preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
                    }
                    Insets insets = panelMergeBranch.getInsets();
                    preferredSize.width += insets.right;
                    preferredSize.height += insets.bottom;
                    panelMergeBranch.setMinimumSize(preferredSize);
                    panelMergeBranch.setPreferredSize(preferredSize);
                }
            }
            panelBranchOptContainer.add(panelMergeBranch);
            panelMergeBranch.setBounds(80, 40, 620, 85);

            //======== panelDeleteBranch ========
            {
                panelDeleteBranch.setVisible(false);
                panelDeleteBranch.setLayout(null);

                //---- labelaDeleteSource ----
                labelaDeleteSource.setText("\u5220\u9664\u5206\u652f\uff1a");
                panelDeleteBranch.add(labelaDeleteSource);
                labelaDeleteSource.setBounds(0, 25, 70, 17);
                panelDeleteBranch.add(textFieldDeleteSource);
                textFieldDeleteSource.setBounds(65, 20, 415, 30);

                //---- btnConfirmDelete ----
                btnConfirmDelete.setText("\u5220\u9664");
                btnConfirmDelete.addActionListener(e -> btnConfirmDeleteActionPerformed(e));
                panelDeleteBranch.add(btnConfirmDelete);
                btnConfirmDelete.setBounds(500, 10, 100, 50);

                {
                    // compute preferred size
                    Dimension preferredSize = new Dimension();
                    for(int i = 0; i < panelDeleteBranch.getComponentCount(); i++) {
                        Rectangle bounds = panelDeleteBranch.getComponent(i).getBounds();
                        preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
                        preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
                    }
                    Insets insets = panelDeleteBranch.getInsets();
                    preferredSize.width += insets.right;
                    preferredSize.height += insets.bottom;
                    panelDeleteBranch.setMinimumSize(preferredSize);
                    panelDeleteBranch.setPreferredSize(preferredSize);
                }
            }
            panelBranchOptContainer.add(panelDeleteBranch);
            panelDeleteBranch.setBounds(80, 40, 620, 85);

            //======== panelCheckputBranch ========
            {
                panelCheckputBranch.setVisible(false);
                panelCheckputBranch.setLayout(null);

                //---- labelaCheckoutSource ----
                labelaCheckoutSource.setText("\u5207\u6362\u5206\u652f\uff1a");
                panelCheckputBranch.add(labelaCheckoutSource);
                labelaCheckoutSource.setBounds(0, 25, 70, 17);
                panelCheckputBranch.add(textFieldCheckoutSource);
                textFieldCheckoutSource.setBounds(65, 20, 415, 30);

                //---- btnConfirmCheckout ----
                btnConfirmCheckout.setText("\u5207\u6362");
                btnConfirmCheckout.addActionListener(e -> btnConfirmCheckoutActionPerformed(e));
                panelCheckputBranch.add(btnConfirmCheckout);
                btnConfirmCheckout.setBounds(500, 10, 100, 50);
            }
            panelBranchOptContainer.add(panelCheckputBranch);
            panelCheckputBranch.setBounds(80, 40, 620, 85);

            {
                // compute preferred size
                Dimension preferredSize = new Dimension();
                for(int i = 0; i < panelBranchOptContainer.getComponentCount(); i++) {
                    Rectangle bounds = panelBranchOptContainer.getComponent(i).getBounds();
                    preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
                    preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
                }
                Insets insets = panelBranchOptContainer.getInsets();
                preferredSize.width += insets.right;
                preferredSize.height += insets.bottom;
                panelBranchOptContainer.setMinimumSize(preferredSize);
                panelBranchOptContainer.setPreferredSize(preferredSize);
            }
        }
        contentPane.add(panelBranchOptContainer);
        panelBranchOptContainer.setBounds(5, 255, 705, 125);

        {
            // compute preferred size
            Dimension preferredSize = new Dimension();
            for(int i = 0; i < contentPane.getComponentCount(); i++) {
                Rectangle bounds = contentPane.getComponent(i).getBounds();
                preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
                preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
            }
            Insets insets = contentPane.getInsets();
            preferredSize.width += insets.right;
            preferredSize.height += insets.bottom;
            contentPane.setMinimumSize(preferredSize);
            contentPane.setPreferredSize(preferredSize);
        }
        pack();
        setLocationRelativeTo(getOwner());
        // JFormDesigner - End of component initialization  //GEN-END:initComponents
    }

    // JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
    private JMenuBar menuBar1;
    private JMenu menuUserInfo;
    private JMenuItem menuItemUserInfo;
    private JScrollPane scrollPane1;
    private JTable table1;
    private JLabel labelTableTitle;
    private JPanel panelBranchOptContainer;
    private JLabel label1;
    private JComboBox<String> comboBoxOpt;
    private JPanel panelCreateBranch;
    private JLabel labelCreateSource;
    private JLabel labelCreateTarget;
    private JTextField textFieldCreateSource;
    private JTextField textFieldCreateTarget;
    private JButton btnConfirmCreate;
    private JPanel panelMergeBranch;
    private JLabel labelaMergeSource;
    private JLabel labelMergeTarget;
    private JTextField textFieldMergeSource;
    private JTextField textFieldMergeTarget;
    private JButton btnConfirmMerge;
    private JPanel panelDeleteBranch;
    private JLabel labelaDeleteSource;
    private JTextField textFieldDeleteSource;
    private JButton btnConfirmDelete;
    private JPanel panelCheckputBranch;
    private JLabel labelaCheckoutSource;
    private JTextField textFieldCheckoutSource;
    private JButton btnConfirmCheckout;
    // JFormDesigner - End of variables declaration  //GEN-END:variables

    /**
     * 下拉框的数据项
     *
     * @return
     */
    private ComboBoxItem[] getComboBoxItems() {
        return Arrays.stream(BranchOperateEnum.values())
                .map(e -> new ComboBoxItem(e.getKey(), e.getName()))
                .toArray(ComboBoxItem[]::new);
    }

    /**
     * 初始化项目下的 git 仓库
     */
    private List<Repository> getProjectRepository() {
        String basePath = project.getBasePath();
        if (StringUtil.isEmpty(basePath)) {
            return new ArrayList<>();
        }
        // 获取当前项目下的 git 目录
//        return GitUtil.findGitDirs(new File(basePath));
        return GitUtil.findGitDirs(ProjectUtil.get());
    }

    /**
     * 获取表格数据
     *
     * @return
     */
    private TableModel getTableModel() {
        List<Repository> repositories = getProjectRepository();
        CheckBoxTableModel model = new CheckBoxTableModel(List.of(COLUMN_NAME_FIRST, COLUMN_NAME_SECOND));
        List<List<Object>> rowDataset = repositories.stream()
                .map(gitDir -> Lists.newArrayList(Boolean.FALSE, gitDir))
                .collect(Collectors.toList());
        model.setRowDataList(rowDataset);
        return model;
    }

    /**
     * 设置表格宽度
     */
    private void renderTableWidth() {
        // 设置列宽
        TableColumn column = table1.getColumn(COLUMN_NAME_FIRST);
        column.setPreferredWidth(50);
        column.setMaxWidth(50);
        column.setMinWidth(50);
    }

    /**
     * 设置分支操作的 panel 全部为 show 类型
     *
     * @param show true 显示，false 隐藏
     */
    private void setAllBranchOptPanelVisible(boolean show) {
        Component[] components = panelBranchOptContainer.getComponents();
        for (Component component : components) {
            if (component instanceof JPanel) {
                component.setVisible(show);
            }
        }
    }
}
